package at.tuwien.seminar.scrum1.view.reservation.list;

import at.tuwien.seminar.scrum1.configuration.Configuration;
import at.tuwien.seminar.scrum1.model.Bill;
import at.tuwien.seminar.scrum1.model.Customer;
import at.tuwien.seminar.scrum1.model.Reservation;
import at.tuwien.seminar.scrum1.model.Room;
import at.tuwien.seminar.scrum1.provider.AjaxDataProvider;
import at.tuwien.seminar.scrum1.provider.DataProvider;
import at.tuwien.seminar.scrum1.provider.IListLoading;
import at.tuwien.seminar.scrum1.proxies.CustomerProxy;
import at.tuwien.seminar.scrum1.proxies.ReservationProxy;
import at.tuwien.seminar.scrum1.view.bill.list.BillList;
import at.tuwien.seminar.scrum1.view.customer.create.CreateCustomer;
import at.tuwien.seminar.scrum1.view.customer.list.CustomerList;
import at.tuwien.seminar.scrum1.view.reservation.create.CreateReservation;
import at.tuwien.seminar.scrum1.view.room.list.RoomList;
import at.tuwien.seminar.scrum1.view.titlepage.TitlePage;
import at.tuwien.seminar.scrum1.view.wicket.column.CustomerColumn;
import at.tuwien.seminar.scrum1.view.wicket.customer.CustomerDeleteActionPanel;
import at.tuwien.seminar.scrum1.view.wicket.customer.CustomerUpdateActionPanel;
import at.tuwien.seminar.scrum1.view.wicket.reservation.ReservationCloseActionPanel;
import at.tuwien.seminar.scrum1.view.wicket.reservation.ReservationDeleteActionPanel;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.DefaultDataTable;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ReservationList extends WebPage implements IListLoading<Reservation>{

    private List<Reservation> initList = null;
    private List<Reservation> list = null;

    private String search;
    private DefaultDataTable table;

	public ReservationList(List<Reservation> reservations) {


        list = reservations;
        initList = reservations;

         add(new Link<Room>("roomLink") {

			@Override
			public void onClick() {
				setResponsePage(new RoomList());
			}

		});
		add(new Link<Customer>("customerLink") {

			@Override
			public void onClick() {
				setResponsePage(new CustomerList());
			}

		});

        add(new Link<Customer>("reservationLink") {

			@Override
			public void onClick() {
				setResponsePage(new ReservationList(ReservationProxy.getInstance().getAll()));
			}

		});

         add(new Link<Bill>("billLink") {

			@Override
			public void onClick() {
				setResponsePage(new BillList());
			}

		});

		final SortableDataProvider<Reservation> dataProvider = new AjaxDataProvider<Reservation>("startDate", this);

		List<IColumn<Reservation>> columns = new ArrayList<IColumn<Reservation>>();

		columns.add(new PropertyColumn<Reservation>(new Model<String>("Raum"), "room.name",
				"room.name"));

		columns.add(new PropertyColumn<Reservation>(new Model<String>("Preis"), "price",
		"price"));

		columns.add(new PropertyColumn<Reservation>(new Model<String>("Rabatt"), "discount",
				"discount"));

		columns.add(new PropertyColumn<Reservation>(new Model<String>("Start"), "startDate",
			"startDate"));

		columns.add(new PropertyColumn<Reservation>(new Model<String>("Ende"), "endDate",
			"endDate"));

        columns.add(new CustomerColumn<Reservation>(new Model<String>("Kunde")));

		columns.add(new AbstractColumn<Reservation>(new Model<String>(""))
		        {
		            public void populateItem(Item<ICellPopulator<Reservation>> cellItem, String componentId,
		                IModel<Reservation> model)
		            {
		                cellItem.add(new ReservationDeleteActionPanel(componentId, model));
		            }
		        });

        columns.add(new AbstractColumn<Reservation>(new Model<String>(""))
		        {
		            public void populateItem(Item<ICellPopulator<Reservation>> cellItem, String componentId,
		                IModel<Reservation> model)
		            {
		                cellItem.add(new ReservationCloseActionPanel(componentId, model));
		            }
		        });


		add(table = new DefaultDataTable<Reservation>("datatable", columns, dataProvider,
				Configuration.ROWSPERPAGE));

		add(new Link<Customer>("back") {

			@Override
			public void onClick() {
				setResponsePage(new TitlePage());

			}

		});

         Form<?> form = new Form("form");

        table.setOutputMarkupId(true);

        form.add(new AutoCompleteTextField<String>("search", new PropertyModel<String>(this, "search")) {
            @Override
            protected Iterator<String> getChoices(String input) {
                List<String> reservations = new ArrayList<String>();

                for (Reservation reservation : ReservationProxy.getInstance().getAll()) {

                    String searchString = reservation.getRoom().getName() + " [" + reservation.getRoom().getId() + "]";

                    if (searchString.contains(input)) {
                        reservations.add(searchString);
                    }
                }

                return reservations.iterator();
            }

        }.add(new AjaxFormComponentUpdatingBehavior("onkeypress") {

            @Override
            protected void onUpdate(AjaxRequestTarget ajaxRequestTarget) {
                if (search == null) {
                    search = "";
                }

                if (search != null) {
                    list.clear();

                    for (Reservation reservation : ReservationProxy.getInstance().getAll()) {
                        String searchString = reservation.getRoom().getName() + " [" + reservation.getRoom().getId() + "]";

                        if (searchString.contains(search)) {
                                list.add(reservation);
                            }
                        }

                        ajaxRequestTarget.addComponent(table);
                    }
                }
        }).add(new AjaxFormComponentUpdatingBehavior("onchange") {

            @Override
            protected void onUpdate(AjaxRequestTarget ajaxRequestTarget) {
                if (search == null) {
                    search = "";
                }

                if (search != null) {
                    list.clear();

                    for (Reservation reservation : ReservationProxy.getInstance().getAll()) {
                        String searchString = reservation.getRoom().getName() + " [" + reservation.getRoom().getId() + "]";

                        if (searchString.contains(search)) {
                                list.add(reservation);
                            }
                        }

                        ajaxRequestTarget.addComponent(table);
                    }
                }
        }));


		form.add(new Link<Customer>("newReservationLink") {

            @Override
            public void onClick() {
                setResponsePage(new CreateReservation());
            }

        });

        add(form);
	}

    public List<Reservation> getList() {
        return list;
    }

    public String getSearch() {
        return search;
    }

    public void setSearch(String search) {
        this.search = search;
    }
}
